package com.cn.udp;

import com.alibaba.fastjson.JSON;

import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.charset.Charset;
import java.util.*;


public class UDPServer extends Thread {

    public void run () {
        Selector selector = null ;
        DatagramChannel channel = null;
        Map<String,InetSocketAddress> mapAddr = new HashMap<>();
        int udpPort=5000;
        try {
            channel = DatagramChannel.open ();
            DatagramSocket socket = channel.socket();
            channel.configureBlocking(false);
            socket.bind(new InetSocketAddress(udpPort));
            System.out.println("server start!");
            selector = Selector.open () ;
            channel.register ( selector, SelectionKey.OP_READ ) ;
        } catch ( Exception e ) {
            e.printStackTrace () ;
        }

        ByteBuffer byteBuffer = ByteBuffer.allocate (100) ;
        while (true){
            try {
                int eventsCount = selector.select() ;
                if ( eventsCount > 0 ) {
                    Set selectedKeys = selector.selectedKeys () ;
                    Iterator iterator = selectedKeys.iterator () ;
                    while ( iterator.hasNext ()) {
                        SelectionKey sk = ( SelectionKey ) iterator.next () ;
                        iterator.remove () ;
                        if ( sk.isReadable ()) {
                            //在这里datagramChannel与channel实际是同一个对象
                            DatagramChannel datagramChannel = ( DatagramChannel ) sk.channel () ;
                            byteBuffer.clear();
//                            SocketAddress sa = datagramChannel.receive(byteBuffer) ;

                            InetSocketAddress sa = (InetSocketAddress) datagramChannel.receive(byteBuffer);

                            System.out.println(JSON.toJSONString(sa));
                            byteBuffer.flip();

                            // 测试：通过将收到的ByteBuffer首先通过缺省的编码解码成CharBuffer 再输出
                            CharBuffer charBuffer = Charset.defaultCharset ().decode( byteBuffer ) ;
                            System.out.println ( "receive message:" + charBuffer.toString()) ;

//                            String echo = "server reply!";
//                            ByteBuffer buffer = Charset.defaultCharset ().encode(echo);
                            Thread.sleep(1000);//延时
//                            datagramChannel.send(buffer,sa);

                            String ipPort = sa.toString();
                            if(!mapAddr.containsKey(ipPort)){ //如果沒有在列表中，那就加進列表中
                                mapAddr.put(ipPort,sa);
                            }
                            ByteBuffer buffer2 = Charset.defaultCharset ().encode(JSON.toJSONString(mapAddr.values()));
                            datagramChannel.send(buffer2,sa);


                        }
                    }//while iterator
                }//if
            } catch ( Exception e ) {
                e.printStackTrace () ;
            }
        }//while

    }

    public static void main ( String [] args ) {
        new UDPServer().start() ;
    }
}

